//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "poligono.h"
#define LONG_NORM_DIBU 30

//---------------------------------------------------------------------------
Poligono::Poligono(vector<PV2D*>* cont,GLfloat cR, GLfloat cG, GLfloat cB){

        contorno = cont;
        normales = new vector<PV2D*>();
        normalesDibu = new vector<PV2D*>();


        r = cR; g = cG; b = cB;

        calcularNormal();
}


Poligono::~Poligono()
{
         if (contorno){
                PV2D* p;
                while (!contorno->empty()){
                        p = contorno->back();
                        if (p) delete p;
		        contorno->pop_back();
                }
        }
        delete contorno;
        contorno = 0;

        if (normales){
                PV2D* p;
                while (!normales->empty()){
                        p = normales->back();
                        if (p) delete p;
		        normales->pop_back();
                }
        }
        delete normales;
        normales = 0;

        if (normalesDibu){
                PV2D* p;
                while (!normalesDibu->empty()){
                        p = normalesDibu->back();
                        if (p) delete p;
		        normalesDibu->pop_back();
                }
        }
        delete normalesDibu;
        normalesDibu = 0;
}

bool Poligono::interseccionVSBall(Ball* b, float & tHit,PV2D*& normalLocal)
{

        /*Usaremos estos nombres para la semejanza con el algoritmo
        siendo tHit == tIn*/

        float ttHit;
        float tIn = 0.0;
        float tOut = 1.0;
        int i =0 ;

        //casos
        bool paralelismoAgudo = false;
        bool paralelismoRecto = false;
        bool entrada = false;
        bool salida = false;


        bool encontrado = false;
        float num,den;
        PV2D* vecPiP;
        PV2D* centroBall = b->getCentro();

        while (!encontrado && i < contorno->size()){
                vecPiP = *centroBall-*contorno->at(i);
                num = vecPiP->prodEscalar(normales->at(i));
                delete vecPiP;

                den = normales->at(i)->prodEscalar(b->getV());

                //hay paralelismo si den == 0
                if (den == 0){
                        paralelismoAgudo = -num > 0;
                        paralelismoRecto = num == 0;

                        if (paralelismoAgudo || paralelismoRecto)
                                encontrado = true;
                }
                else{
                        entrada = den < 0;
                        salida = den > 0;

                        ttHit = -num/den;

                        if (entrada){
                                if (ttHit > tIn){
                                        tIn = ttHit;
                                        normalLocal = normales->at(i);
                                }
                        }
                        else if (salida)
                                tOut = min (tOut, ttHit);

                        encontrado = tIn > tOut;
                }
                i++;
        }
        tHit = tIn;
        delete centroBall;

        return !encontrado;
}

Poligono::calcularNormal()
{
        /*Calculamos el vector que va de un vertice a otro para poder
        calcular la normal*/
        //0-1
        PV2D* vec;
        PV2D* n;
        PV2D* nV;
        PV2D* nVNL;

        int j;
        for (int i = 0; i < contorno->size(); i++){
                j = (i+1)%contorno->size();
                vec = *contorno->at(j)-*contorno->at(i);
                n = vec->getNormalDer();
                normales->push_back(n);

                nV = n->getVectorNorm();
                nVNL = *nV*LONG_NORM_DIBU;
                normalesDibu->push_back(*contorno->at(i)+*nVNL);

                delete vec;
                delete nV;
                delete nVNL;
        }
}

void Poligono::draw(bool b)
{


        glColor3f(this->r,this->g,this->b);

	glBegin(GL_POLYGON); //cambiar
                for (int i = 0; i < contorno->size(); i ++)
                        glVertex2f(contorno->at(i)->getX(), contorno->at(i)->getY());
	glEnd();

        if (b){
                glColor3f(1.0,1.0,0.0);
                glBegin(GL_LINES);
                for (int i = 0; i < contorno->size(); i++){
                         glVertex2f(contorno->at(i)->getX(), contorno->at(i)->getY());
                         glVertex2f(normalesDibu->at(i)->getX(), normalesDibu->at(i)->getY());
                }
                glEnd();
        }
}



#pragma package(smart_init)

